﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using QuickGraph;
using QuickGraph.Algorithms;
using QuickGraph.Algorithms.ConnectedComponents;
using QuickGraph.Algorithms.Search;

namespace www.coursera.algo.org.ProblemQuestion._4
{
    class Program
    {

        public static int depth = 0;
        public static Dictionary<string, int> f;
        public static Dictionary<string, int> d;
        public static int currentLabel;

        private static List<string> tree = new List<string>();
        private static List<double> SCCCount = new List<double>();


        public static Dictionary<int, int> DiscoveryVertex = new Dictionary<int, int>();
        public static Dictionary<int, int> FinishVertex = new Dictionary<int, int>();
        public static List<Edge<int>> EdgeVertex = new List<Edge<int>>();
        public static int count;

        static void Main(string[] args)
        {
            var graph = new BidirectionalGraph<int, Edge<int>>();


            string fileName = "SCC.txt";

            #region intitlize graph

            char[] delimiterChars = { ' ', ',', '.', ':', '\t' };


            using (StreamReader sr = new StreamReader("TestCases\\" + fileName))
            {
                String line;
                // Read and display lines from the file until the end of
                // the file is reached.
                while ((line = sr.ReadLine()) != null)
                {
                    string[] list = line.Split(delimiterChars, StringSplitOptions.RemoveEmptyEntries);

                    int v = Convert.ToInt32((list[0]));
                    int w = Convert.ToInt32((list[1]));
                    //if(v!=w)
                    {
                        if (!graph.ContainsVertex(v))
                        {
                            graph.AddVertex(v);

                        }
                        if (!graph.ContainsVertex(w))
                        {
                            graph.AddVertex(w);

                        }
                        graph.AddEdge(new Edge<int>(v, w));
                    }






                }

            }

            #endregion


            //var dfs = new DepthFirstSearchAlgorithm<int, Edge<int>>(graph);
            ////do the search


            //dfs.DiscoverVertex += new VertexAction<int>(dfs_DiscoverVertex);
            //dfs.FinishVertex += new VertexAction<int>(dfs_FinishVertex);
            //dfs.TreeEdge += new EdgeAction<int, Edge<int>>(dfs_TreeEdge);
            //dfs.ExamineEdge += new EdgeAction<int, Edge<int>>(dfs_ExamineEdge);
            //dfs.BackEdge += new EdgeAction<int, Edge<int>>(dfs_BackEdge);
            //dfs.ForwardOrCrossEdge += new EdgeAction<int, Edge<int>>(dfs_ForwardOrCrossEdge);





            //dfs.Compute();
            var components = new Dictionary<int, int>();
            var conn = new DebaStronglyConnectedComponentsAlgorithm<int, Edge<int>>(graph, components);

            


            conn.Compute();

            conn.SCCCount.OrderByDescending(p=>p).Take(5).ToList().ForEach(p=>Console.WriteLine(p));

            Console.WriteLine("Done");
            Console.ReadLine();



        }

        #region DFS Events
        static void dfs_ForwardOrCrossEdge(Edge<int> e)
        {

        }

        static void dfs_BackEdge(Edge<int> e)
        {

        }

        static void dfs_ExamineEdge(Edge<int> e)
        {

        }

        static void dfs_TreeEdge(Edge<int> e)
        {


            EdgeVertex.Add(e);
        }

        static void dfs_FinishVertex(int vertex)
        {
            count = count + 1;
            FinishVertex.Add(vertex, count);
        }

        static void dfs_DiscoverVertex(int vertex)
        {

            count = count + 1;
            DiscoveryVertex.Add(vertex, count);
        }
        #endregion


    }


}
